﻿#include "mappic.h"

MapPic::MapPic( QWidget* parent ) : QWidget( parent ), Alloffset( 0, 0 ) {
    ratio  = 1.0;  //初始化图片缩放比例
    action = None;
    pixW   = 639;  //设置图片尺寸
    pixH   = 682;
    pix    = new QPixmap;
    pix->load( ":/pic/src/other/料叉式路线图.png" );
    *pix      = pix->scaled( pixW, pixH, Qt::IgnoreAspectRatio );
    label_map = new QLabel;
    label_map->setMinimumSize( 600, 600 );
    label_map->setMaximumSize( 600, 600 );
    label_map->setScaledContents( true );  //自动调整图片
    QPushButton* button_enlarge = new QPushButton( "放大" );
    QPushButton* button_narrow  = new QPushButton( "缩小" );
    QHBoxLayout* mainLayout     = new QHBoxLayout( this );
    QVBoxLayout* buttonlayout   = new QVBoxLayout();

    button_enlarge->setStyleSheet( "QPushButton{background-color: rgb(0, 198, 198); color: white;}" );
    button_enlarge->setMinimumSize( 128, 40 );
    button_enlarge->setMaximumSize( 128, 40 );
    button_narrow->setStyleSheet( "QPushButton{background-color: rgb(255, 170, 0); color: white;}" );
    button_narrow->setMinimumSize( 128, 40 );
    button_narrow->setMaximumSize( 128, 40 );
    //水平布局
    buttonlayout->addItem( new QSpacerItem( 40, 40, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
    buttonlayout->addWidget( button_enlarge );
    buttonlayout->addItem( new QSpacerItem( 40, 40, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
    buttonlayout->addWidget( button_narrow );
    buttonlayout->addItem( new QSpacerItem( 40, 40, QSizePolicy::Expanding, QSizePolicy::Minimum ) );

    //垂直布局
    mainLayout->addWidget( label_map );
    mainLayout->addLayout( buttonlayout );
    connect( button_enlarge, SIGNAL( clicked() ), this, SLOT( sltEnlargeMap() ) );
    connect( button_narrow, SIGNAL( clicked() ), this, SLOT( sltNarrowMap() ) );
}

void MapPic::paintEvent( QPaintEvent* event ) {
    QPainter painter( this );
    int      NowW = static_cast< int >( ratio * pixW );
    int      NowH = static_cast< int >( ratio * pixH );

    if ( action == Amplification )  //缩小
    {
        ratio -= 0.1 * ratio;
        if ( ratio < 0.18 ) {
            ratio = 0.1;
        }
    }
    else if ( action == Shrink )  //放大
    {
        ratio += 0.1 * ratio;
        if ( ratio > 4.5 ) {
            ratio = 5.000;
        }
    }
    if ( ( action == Amplification ) || ( action == Shrink ) )  //更新图片
    {
        NowW = static_cast< int >( ratio * pixW );
        NowH = static_cast< int >( ratio * pixH );
        pix->load( ":/pic/src/other/料叉式路线图.png" );
        *pix   = pix->scaled( NowW, NowH, Qt::IgnoreAspectRatio );
        action = None;
    }

    if ( action == Move )  //移动
    {
        int offsetx = Alloffset.x() + offset.x();
        Alloffset.setX( offsetx );

        int offsety = Alloffset.y() + offset.y();
        Alloffset.setY( offsety );
        action = None;
    }

    if ( abs( Alloffset.x() ) >= ( label_map->width() / 2 + NowW / 2 - 10 ) )  //限制X偏移值
    {
        if ( Alloffset.x() > 0 ) {
            Alloffset.setX( label_map->width() / 2 + NowW / 2 - 10 );
        }
        else {
            Alloffset.setX( -label_map->width() / 2 + -NowW / 2 + 10 );
        }
    }
    if ( abs( Alloffset.y() ) >= ( label_map->height() / 2 + NowH / 2 - 10 ) )  //限制Y偏移值
    {
        if ( Alloffset.y() > 0 ) {
            Alloffset.setY( label_map->height() / 2 + NowH / 2 - 10 );
        }
        else {
            Alloffset.setY( -label_map->height() / 2 + -NowH / 2 + 10 );
        }
    }

    int x = label_map->width() / 2 + Alloffset.x() - NowW / 2;
    if ( x < 0 ) {
        x = 0;
    }

    int y = label_map->height() / 2 + Alloffset.y() - NowH / 2;
    if ( y < 0 ) {
        y = 0;
    }

    int sx = NowW / 2 - label_map->width() / 2 - Alloffset.x();
    if ( sx < 0 ) {
        sx = 0;
    }

    int sy = NowH / 2 - label_map->height() / 2 - Alloffset.y();
    if ( sy < 0 ) {
        sy = 0;
    }

    int w = ( NowW - sx ) > label_map->width() ? label_map->width() : ( NowW - sx );
    if ( w > ( label_map->width() - x ) ) {
        w = label_map->width() - x;
    }

    int h = ( NowH - sy ) > label_map->height() ? label_map->height() : ( NowH - sy );
    if ( h > ( label_map->height() - y ) ) {
        h = label_map->height() - y;
    }

    painter.drawRect( label_map->x() - 1, label_map->y() - 1, label_map->width() + 1, label_map->height() + 1 );  //画框
    painter.drawTiledPixmap( x + label_map->x(), y + label_map->y(), w, h, *pix, sx, sy );
    event->accept();
}

bool MapPic::event( QEvent* event ) {
    static bool   press = false;
    static QPoint PreDot;

    if ( event->type() == QEvent::MouseButtonPress ) {
        QMouseEvent* mouse = dynamic_cast< QMouseEvent* >( event );

        //判断鼠标是否是左键按下,且鼠标位置是否在绘画区域
        if ( ( mouse->button() == Qt::LeftButton ) && label_map->geometry().contains( mouse->pos() ) ) {
            press = true;
            QApplication::setOverrideCursor( Qt::OpenHandCursor );  //设置鼠标样式

            PreDot = mouse->pos();
        }
    }
    else if ( event->type() == QEvent::MouseButtonRelease ) {
        QMouseEvent* mouse = dynamic_cast< QMouseEvent* >( event );

        //判断鼠标是否是左键释放,且之前是在绘画区域
        if ( ( mouse->button() == Qt::LeftButton ) && press ) {
            QApplication::setOverrideCursor( Qt::ArrowCursor );  //改回鼠标样式
            press = false;
        }
    }

    if ( event->type() == QEvent::MouseMove )  //移动图片
    {
        if ( press ) {
            QMouseEvent* mouse = dynamic_cast< QMouseEvent* >( event );

            offset.setX( mouse->x() - PreDot.x() );
            offset.setY( mouse->y() - PreDot.y() );
            PreDot = mouse->pos();
            action = Move;
            this->update();
        }
    }
    return QWidget::event( event );
}

void MapPic::wheelEvent( QWheelEvent* e ) {
    if ( e->delta() > 0 )  //上滑,缩小

    {
        action = Shrink;
        this->update();
    }
    else  //下滑,放大
    {
        action = Amplification;
        this->update();
    }

    e->accept();
}

void MapPic::sltEnlargeMap() {
    action = Shrink;
    this->update();
}

void MapPic::sltNarrowMap() {
    action = Amplification;
    this->update();
}
